home *** CD-ROM | disk | FTP | other *** search
- /*
- * Database builder for MMDF address database
- *
- * Command line:
- * dbmbuild [-flags] [-t tailorfile] [outfile]
- *
- * where flags are:
- * d - debugging output
- * v - verbose output
- * k - keep going if a table is missing
- * n - make a new dbm file from scratch
- * t - alternate tailorfile
- *
- * output-file is name of EXISTING dbm file to insert entires.
- * Note it is two files, an output-file.dir and an output-file.pag.
- *
- * No arguments defaults to -n.
- */
-
- #include "util.h"
- #include "mmdf.h"
- #include "ch.h"
- #include "dm.h"
- #include "chdbm.h"
-
- extern Table **tb_list; /* order tables searched */
- extern Domain **dm_list; /* ordr domain tables searched */
- extern Chan **ch_tbsrch; /* order chans searched */
-
- extern char *blt();
- extern char *multcat();
- extern char *tbldfldir;
- extern char *tbldbm;
- extern char *lckdfldir;
- extern char *mmtailor;
-
- typedef struct
- {
- char *dptr;
- int dsize;
- } datum;
-
- extern datum fetch ();
-
- typedef struct dbmentry
- {
- char dbmvalue[1];
- } Entry;
-
- int error;
- int Debug;
- int Verbose;
- int newflag;
- int keepgoing;
- char dbfile[128];
- char *dblock;
- int lckfd;
-
- char dbmstr[] = "DBM$$";
- /* string for locking the database */
-
- /*
- * Main procedure.
- * process arguments, set flags and invoke file processing.
- * clean up and exit properly.
- */
-
- main(argc, argv)
- char **argv;
- {
- int ind;
- char *p;
- char *outfile;
- register Table *tblptr;
- char *prog;
-
- prog = argv[0];
-
- argv++; argc--;
- outfile = (char *)0;
-
- if (argc == 0)
- newflag++;
-
- while(argc-- > 0)
- {
- if (Debug)
- fprintf (stderr, "arg='%s'\n", *argv);
- p = *argv++;
- if(*p == '-')
- {
- while(*++p)
- switch(*p)
- {
- case 'O': /* Obsolete, ignored */
- break;
-
- case 'd':
- Debug++;
- break;
-
- case 'k':
- keepgoing++;
- break;
-
- case 'n':
- newflag++;
- break;
-
- case 'v':
- Verbose++;
- break;
-
- case 't':
- if (argc--==2) newflag++;
- mmtailor = *argv++;
- break;
-
- default:
- fprintf (stderr,"Unknown flag %c\n",*p);
- break;
- }
- }
- else
- {
- outfile = p;
- break;
- }
- }
-
- mmdf_init(prog);
-
- if (outfile == 0) /* use default database */
- {
- if (tbldbm == 0 || tbldbm[0] == '\0')
- {
- fprintf (stderr, "no default data base, in 'tbldbm' variable\n");
- exit (NOTOK);
- }
- outfile = tbldbm;
- }
-
- /*
- * Check for existence first
- */
- error = 0;
- if (argc <= 0) {
- for (ind = 0; dm_list[ind] != (Domain *)0; ind++)
- error += check(dm_list[ind] -> dm_table);
-
- for (ind = 0; ch_tbsrch[ind] != (Chan *) 0; ind++)
- {
- error += check(ch_tbsrch[ind] -> ch_table);
-
- if ((tblptr = ch_tbsrch[ind] -> ch_insource) != (Table *) 0)
- error += check(tblptr);
- if ((tblptr = ch_tbsrch[ind] -> ch_outsource) != (Table *) 0)
- error += check(tblptr);
- if ((tblptr = ch_tbsrch[ind] -> ch_indest) != (Table *) 0)
- error += check(tblptr);
- if ((tblptr = ch_tbsrch[ind] -> ch_outdest) != (Table *) 0)
- error += check(tblptr);
- }
-
- for (ind = 0; (tblptr = tb_list[ind]) != (Table *) 0; ind++)
- error += check (tblptr);
- } else {
- while (argc-- > 0)
- {
- if ((tblptr = tb_nm2struct (*argv++)) == (Table *) NOTOK)
- {
- fprintf (stderr, "Table '%s' is unknown\n", *--argv);
- error++;
- };
- error += check(tblptr);
- }
- }
-
- if (error) {
- fprintf (stderr, "Some tables are missing. dbmbuild aborted.\n");
- exit(9);
- }
-
- getfpath (outfile, tbldfldir, dbfile);
- dblock = multcat (dbfile, ".lck", (char *)0);
- (void) close( creat( dblock, 0444 ));
-
- if ((lckfd = lk_open(dblock, 0, (char *)0, (char *)0, 10)) < 0) {
- perror (dblock);
- fprintf (stderr, "Data base %s is locked. Try again later.\n",
- dbfile);
- exit (NOTOK);
- }
-
- if (!theinit (newflag))
- cleanup (-1);
-
- if (argc <= 0)
- {
- /*
- * Now process for real!
- */
- for (ind = 0; dm_list[ind] != (Domain *)0; ind++)
- {
- if (Debug)
- fprintf (stderr, "Domain '%s'\n", dm_list[ind] -> dm_show);
- process (dm_list[ind] -> dm_table);
- }
-
- for (ind = 0; ch_tbsrch[ind] != (Chan *) 0; ind++)
- {
- if (Debug)
- fprintf (stderr, "Chan '%s'\n", ch_tbsrch[ind] -> ch_show);
- process (ch_tbsrch[ind] -> ch_table);
-
- if ((tblptr = ch_tbsrch[ind] -> ch_insource) != (Table *) 0)
- {
- if (Debug)
- fprintf (stderr, "Source inbound filter\n");
- if (Verbose || Debug)
- putc ('\t', stderr);
- process (tblptr);
- }
- if ((tblptr = ch_tbsrch[ind] -> ch_outsource) != (Table *) 0)
- {
- if (Debug)
- fprintf (stderr, "Source outbound filter\n");
- if (Verbose || Debug)
- putc ('\t', stderr);
- process (tblptr);
- }
- if ((tblptr = ch_tbsrch[ind] -> ch_indest) != (Table *) 0)
- {
- if (Debug)
- fprintf (stderr, "Destination inbound filter\n");
- if (Verbose || Debug)
- putc ('\t', stderr);
- process (tblptr);
- }
- if ((tblptr = ch_tbsrch[ind] -> ch_outdest) != (Table *) 0)
- {
- if (Debug)
- fprintf (stderr, "Destination outbound filter\n");
- if (Verbose || Debug)
- putc ('\t', stderr);
- process (tblptr);
- }
- }
-
- for (ind = 0; (tblptr = tb_list[ind]) != (Table *) 0; ind++)
- { /* in case table used by chan */
- if (tblptr -> tb_fp != (FILE *) EOF)
- {
- if (Debug)
- fprintf (stderr, "Table '%s'\n", tblptr -> tb_name);
- process (tblptr);
- }
- }
- }
- else
- while (argc-- > 0)
- {
- if ((tblptr = tb_nm2struct (*argv++)) == (Table *) NOTOK)
- {
- (void) fflush (stdout);
- fprintf (stderr, "Table '%s' is unknown\n", *--argv);
- cleanup (-1);
- };
- process (tblptr);
- }
-
- cleanup (theend (newflag));
- }
-
- /**/
-
- theinit (new) /* initialize the dbm files */
- int new;
- {
- char tmpfile[100];
-
- if (new) /* start with fresh files */
- {
- if (Verbose || Debug)
- fprintf (stderr, "Temporary database: %s$\n", dbfile);
- (void) sprintf (tmpfile, "%s$.pag", dbfile);
- if(Debug)
- fprintf (stderr, "creating '%s'\n", tmpfile);
-
- if (close (creat (tmpfile, 0644)) < 0)
- { /* create and/or zero the file */
- fprintf (stderr, "could not creat '%s': ", tmpfile);
- perror ("");
- cleanup (-1);
- }
- chmod (tmpfile, 0644); /* in case umask screwed us */
-
- (void) sprintf (tmpfile, "%s$.dir", dbfile);
- if(Debug)
- fprintf (stderr, "creating '%s'\n", tmpfile);
-
- if (close (creat (tmpfile, 0644)) < 0)
- { /* create and/or zero the file */
- fprintf (stderr, "could not creat '%s': ", tmpfile);
- perror ("");
- cleanup (-1);
- }
- chmod (tmpfile, 0644); /* in case umask screwed us */
- (void) sprintf (tmpfile, "%s$", dbfile);
- return (dbfinit (tmpfile));
- }
-
- return (dbfinit (dbfile));
- }
-
- theend (new) /* cleanup the dbm files */
- int new;
- {
- char fromfile[100];
- char tofile[100];
-
- #ifdef DBMCACHE
- dbmcachedump();
- #endif
-
- dbfclose();
-
- if (new) /* started with fresh files */
- {
- if (Verbose || Debug)
- fprintf(stderr, "Moving to database: %s\n", dbfile);
-
- (void) sprintf (fromfile, "%s$.pag", dbfile);
- (void) sprintf (tofile, "%s.pag", dbfile);
- if (Debug)
- fprintf (stderr, "moving '%s'\n", fromfile);
-
- (void) unlink (tofile);
-
- if ((link (fromfile, tofile ) < 0) || (unlink (fromfile) < 0))
- { /* create and/or zero the file */
- fprintf (stderr, "could not link to '%s': ", tofile);
- perror ("");
- cleanup (-1);
- }
-
- (void) sprintf (fromfile, "%s$.dir", dbfile);
- (void) sprintf (tofile, "%s.dir", dbfile);
- if(Debug)
- fprintf (stderr, "moving '%s'\n", fromfile);
-
- (void) unlink (tofile);
-
- if ((link (fromfile, tofile ) < 0) || (unlink (fromfile) < 0))
- { /* create and/or zero the file */
- fprintf (stderr, "could not link to '%s': ", tofile);
- perror ("");
- cleanup (-1);
- }
-
- return (TRUE);
- }
-
- return (TRUE);
- }
-
- /*
- * Initialize the dbm file.
- * Fetch the local name datum
- * Init to 1 and store it if there is no datum by that name.
- */
-
- dbfinit(filename)
- char *filename;
- {
- if(dbminit(filename) < 0)
- {
- fprintf (stderr, "could not initialize data base '%s'", filename);
- perror("");
- return (0);
- }
- return (1);
- }
-
- /*
- * Close the dbm datafile.
- * We can't close the file because the library does not provide the call...
- */
-
- dbfclose()
- {
- return (1);
- }
-
- /*
- * Process a sequential file and insert items into the database
- * Opens argument assumes database is initialized.
- */
-
- process (tblptr)
- Table *tblptr;
- {
- datum key, value;
- char tbkey[LINESIZE],
- tbvalue[LINESIZE];
- char *cp;
-
- if (Verbose || Debug)
- fprintf (stderr, tblptr -> tb_fp == (FILE *)EOF ?
- "%s (%s) already done\n" : "%s (%s)\n",
- tblptr -> tb_show, tblptr -> tb_name);
- if (tblptr -> tb_fp == (FILE *)EOF)
- return;
-
- #ifdef NAMESERVER
- if ((tblptr -> tb_flags & TB_SRC) == TB_NS) {
- if (Debug || Verbose)
- fprintf (stderr, " (Nameserver table)\n");
- return;
- }
- #endif /* NAMESERVER */
- if (!tb_open (tblptr, TRUE)) /* gain access to a channel table */
- {
- fprintf (stderr, "could not open table \"%s\" (%s, file = '%s'):\n\t",
- tblptr -> tb_show, tblptr -> tb_name,
- tblptr -> tb_file);
- perror("");
- tblptr -> tb_fp = (FILE *) EOF; /* Don't try again */
- if (keepgoing)
- return;
- cleanup(-1);
- }
-
- while (tb_read (tblptr, tbkey, tbvalue))
- { /* read a table's record */
- switch (tbkey[0])
- {
- case '\0':
- case '#':
- case ';':
- continue; /* empty lines and comments ok */
- }
-
- if(tbvalue[0] == '\0')
- { /* empty value field */
- value.dptr = "";
- value.dsize = 1;
- }
- else
- {
- value.dptr = tbvalue;
- value.dsize = strlen (tbvalue) + 1;
- }
- for (cp = tbkey; *cp != 0; cp++)
- *cp = uptolow(*cp); /* All keys are lower case */
- key.dptr = tbkey;
- key.dsize = strlen (tbkey) + 1;
- if(Debug)
- fprintf (stderr, "(%d)'%s': (%d)'%s'\n",
- key.dsize, key.dptr, value.dsize, value.dptr);
- install(key, value, tblptr -> tb_name);
- }
-
- if (ferror (tblptr -> tb_fp))
- {
- fprintf (stderr, "i/o error with table %s (%s, file = %s): ",
- tblptr -> tb_show, tblptr -> tb_name,
- tblptr -> tb_file);
- perror ("");
- }
- tb_close (tblptr);
- tblptr -> tb_fp = (FILE *) EOF; /* Don't try again */
- }
-
- /*
- * Install a datum into the database..
- * Fetch entry first to see if we have to append
- * name for building entry.
- */
-
- install(key, value, tbname)
- datum key, value;
- char tbname[];
- {
- datum old;
- char newentry[ENTRYSIZE];
- register char *p;
-
- p = newentry;
- old = fetch (key);
- if (old.dptr != NULL) {
- if (Debug) {
- fprintf (stderr, "\tFound old entry\n\t");
- prdatum (old);
- }
-
- p = blt (old.dptr, p, old.dsize - 1);
- *p++ = FS; /* end with a record seperator */
- }
- p = blt (tbname, p, strlen (tbname));
- *p++ = ' ';
- p = blt (value.dptr, p, value.dsize);
-
- old.dptr = newentry;
- old.dsize = p - newentry;
- if (Debug) {
- fprintf (stderr, "\tNew datum\n\t");
- prdatum (old);
- }
- if (store (key, old) < 0) { /* put the datum back */
- fprintf (stderr, "dbmbuild, install: store failed; key='%s', value=",
- key.dptr);
- prdatum (old);
- cleanup (NOTOK);
- }
- return (1);
- }
- /*
- * Print a datum.
- * Takes the datum argument and prints it so that we can read
- * it as either a key or an entry.
- */
-
- prdatum(value)
- datum value;
- {
- int cnt;
- char data[512];
-
- blt (value.dptr, data, value.dsize);
-
- for (cnt = 0; cnt < value.dsize; cnt++) {
- if (value.dptr[cnt] >= ' ' && value.dptr[cnt] <= '~')
- putc (value.dptr[cnt], stderr);
- else
- fprintf (stderr, "<\\%03o>", value.dptr[cnt]);
- }
- putc ('\n', stderr);
- }
-
- check (tblptr)
- Table *tblptr;
- {
- #ifdef NAMESERVER
- if ((tblptr -> tb_flags & TB_SRC) == TB_NS)
- return(0);
- #endif /* NAMESERVER */
- if (tblptr -> tb_fp == (FILE *)EOF)
- return(1); /* We already know its bad */
- if (!tb_open (tblptr, TRUE)) /* gain access to a channel table */
- {
- fprintf (stderr, "could not open table \"%s\" (%s, file = '%s'):\n\t",
- tblptr -> tb_show, tblptr -> tb_name,
- tblptr -> tb_file);
- perror("");
- tblptr -> tb_fp = (FILE *) EOF;
- return(1);
- }
- tb_close (tblptr);
- tblptr -> tb_fp = (FILE *) NULL;
- return(0);
- }
-
- cleanup (exitval)
- int exitval;
- {
- lk_close (lckfd, dblock, (char *)0, (char *)0);
- exit (exitval == TRUE? 0 : 1); /* TRUE is non-zero */
- }
-